vim.cmd([[packadd lsp_signature.nvim]])
vim.cmd([[packadd aerial.nvim]])
vim.cmd([[packadd lspsaga.nvim]])
vim.cmd([[packadd vim-illuminate]])

-- A lsp install tool
local mason = require("mason")
local mason_lsp = require("mason-lspconfig")
local nvim_lsp = require("lspconfig")

mason.setup()
mason_lsp.setup({
	ensure_installed = {
		"lua-language-server",
		"clangd",
	},
})

-- Override diagnostics symbol
require("lspsaga").init_lsp_saga({
	error_sign = "",
	warn_sign = "",
	hint_sign = "",
	infor_sign = "",
})
--[[
require ('lspsaga').setup { -- defaults ...
	debug = false,
	use_saga_diagnostic_sign = true,
	-- diagnostic sign
	error_sign = "",
	warn_sign = "",
	hint_sign = "",
	infor_sign = "",
	diagnostic_header_icon = "   ",
	-- code action title icon
	code_action_icon = " ",
	code_action_prompt = {
		enable = true,
		sign = true,
		sign_priority = 40,
		virtual_text = true,
	},
	finder_definition_icon = "  ",
	finder_reference_icon = "  ",
	max_preview_lines = 10,
	finder_action_keys = {
		open = "o",
		vsplit = "v",
		split = "x",
		quit = "q",
		scroll_down = "<C-n>",
		scroll_up = "<C-p>",
	},
	code_action_keys = {
		quit = "q",
		exec = "<CR>",
	},
	rename_action_keys = {
		quit = "<C-c>",
		exec = "<CR>",
	},
	definition_preview_icon = "  ",
	border_style = "single",
	rename_prompt_prefix = "➤",
	rename_output_qflist = {
		enable = false,
		auto_open_qflist = false,
	},
	server_filetype_map = {},
	diagnostic_prefix_format = "%d. ",
	diagnostic_message_format = "%m %c",
	highlight_prefix = false,
}
]]

local function switch_source_header_splitcmd(bufnr, splitcmd)
	bufnr = nvim_lsp.util.validate_bufnr(bufnr)
	local clangd_client = nvim_lsp.util.get_active_client_by_name(bufnr, "clangd")
	local params = { uri = vim.uri_from_bufnr(bufnr) }
	if clangd_client then
		clangd_client.request("textDocument/switchSourceHeader", params, function(err, result)
			if err then
				error(tostring(err))
			end
			if not result then
				print("Corresponding file can’t be determined")
				return
			end
			vim.api.nvim_command(splitcmd .. " " .. vim.uri_to_fname(result))
		end)
	else
		print("method textDocument/switchSourceHeader is not supported by any servers active on the current buffer")
	end
end

-- Attach plugins while loding the client
local function custom_attach(client)
	require("lsp_signature").on_attach({
		bind = true,
		use_lspsaga = false,
		floating_window = true,
		fix_pos = true,
		hint_enable = true,
		hi_parameter = "Search",
		handler_opts = { "double" },
	})
	-- Disable lsp formatting
	client.resolved_capabilities.document_formatting = true
	client.resolved_capabilities.document_range_formatting = true
	require("aerial").on_attach(client)
	require("illuminate").on_attach(client)
end

local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require("cmp_nvim_lsp").update_capabilities(capabilities)

-- Lsp setups
-- Clangd
function setup_clangd()
	local copy_capabilities = capabilities
	copy_capabilities.offsetEncoding = { "utf-16" }

	nvim_lsp.clangd.setup({
		capabilities = copy_capabilities,
		single_file_support = true,
		-- Disable `clangd`'s format
		on_attach = custom_attach,
		args = {
			"--background-index",
			"-std=c++20",
			"--pch-storage=memory",
			"--clang-tidy",
			"--suggest-missing-includes",
		},
		commands = {
			ClangdSwitchSourceHeader = {
				function()
					switch_source_header_splitcmd(0, "edit")
				end,
				description = "Open source/header in current buffer",
			},
			ClangdSwitchSourceHeaderVSplit = {
				function()
					switch_source_header_splitcmd(0, "vsplit")
				end,
				description = "Open source/header in a new vsplit",
			},
			ClangdSwitchSourceHeaderSplit = {
				function()
					switch_source_header_splitcmd(0, "split")
				end,
				description = "Open source/header in a new split",
			},
		},
	})
end

-- sumneko_lua
function setup_sumneko_lua()
	nvim_lsp.sumneko_lua.setup({
		capabilities = capabilities,
		on_attach = custom_attach,
		settings = {
			Lua = {
				diagnostics = {
					globals = { "vim", "packer_plugins" },
					disable = { "lowercase-global" },
				},
				workspace = {
					library = {
						[vim.fn.expand("$VIMRUNTIME/lua")] = true,
						[vim.fn.expand("$VIMRUNTIME/lua/vim/lsp")] = true,
					},
					maxPreload = 100000,
					preloadFileSize = 10000,
				},
				telemetry = { enable = false },
			},
		},
	})
end

setup_clangd()
setup_sumneko_lua()
